package server

import (
	"sort"
	"strconv"
)

type EzAction func(operation *Operation)
type EzFunc func(operation *Operation)
type PublicData struct {
	V     interface{}
	Read  int
	Write int
	Chan  chan int
}
type EzHandler struct {
	Matcher    string
	Router     *Router
	Action     *EzAction
	Public     map[string]*PublicData //公开数据
	ActionSort []string
	StatusCode int //允许中断
	Actions    map[string]map[string]*EzAction
	CurAction  *EzAction
	IsStop     bool
}

func NewEzHandler(router *Router, action *EzAction) *EzHandler {
	hd := &EzHandler{
		Matcher:    router.Url,
		Router:     router,
		Action:     action,
		Public:     make(map[string]*PublicData),
		ActionSort: make([]string, 0),
		CurAction:  nil,
		StatusCode: 0,
		Actions:    make(map[string]map[string]*EzAction),
		IsStop:     false,
	}
	hd.Add(50, "main", *action)
	return hd
}

func (this *EzHandler) Add(weight int, name string, action EzAction) *EzHandler {
	if weight < 10 {
		weight = 10
	}
	if weight > 100 {
		weight = 99
	}
	//w := strconv.Itoa(weight)
	////w := fmt.Sprintf("%d", weight)
	//_, ok := this.Actions[strconv.Itoa(weight)]
	//if !ok {
	//	this.Actions[w] = map[string]*EzAction{name: &action}
	//} else {
	//	this.Actions[w][name] = &action
	//}
	////重新梳理排序字段
	//tmp := make([]string, 0)
	//for key, _ := range this.Actions {
	//	tmp = append(tmp, key)
	//}
	//sort.Strings(tmp)
	//this.ActionSort = tmp
	return this.SAdd(weight, name, action)
}

// 仅供框架使用，用于一些weight小于10或者大于99的方法的创建
func (this *EzHandler) SAdd(weight int, name string, action EzAction) *EzHandler {
	w := strconv.Itoa(weight)
	//w := fmt.Sprintf("%d", weight)
	_, ok := this.Actions[strconv.Itoa(weight)]
	if !ok {
		this.Actions[w] = map[string]*EzAction{name: &action}
	} else {
		this.Actions[w][name] = &action
	}
	//重新梳理排序字段
	tmp := make([]string, 0)
	for key, _ := range this.Actions {
		tmp = append(tmp, key)
	}
	sort.Strings(tmp)
	this.ActionSort = tmp
	return this
}

func (this *EzHandler) Get(dataName string) interface{} {
	data, ok := this.Public[dataName]
	if !ok {
		return nil
	}
	return data.V
}
func (this *EzHandler) Set(dataName string, data interface{}) {

	find, ok := this.Public[dataName]
	if !ok {
		find = &PublicData{V: data, Read: 0, Write: 0, Chan: make(chan int)}
	}
	find.V = data
	find.Write++
	this.Public[dataName] = find
}

func (this *EzHandler) Run(operation *Operation) {
	operation.Handler = this
	for _, key := range this.ActionSort {
		actions, ok := this.Actions[key]
		if ok {
			groupHandlerTimer := operation.Timer.Add("EzHandler_Weight_" + key)
			for name, action := range actions {
				if this.IsStop {
					return
				}
				groupSonHandlerTimer := operation.Timer.Add("EzHandler_Weight_" + key + "_" + name)
				(*action)(operation)
				groupSonHandlerTimer.Done()

				//todo 这里使用协程似乎是有问题的，后面查查解决一下
			}
			groupHandlerTimer.Done()
		}
	}
}
